1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.android.launcher;
18
19 import android.content.ComponentName;
20 import android.content.ContentResolver;
21 import android.content.ContentValues;
22 import android.content.Intent;
23 import android.content.Context;
24 import android.content.pm.ActivityInfo;
25 import android.content.pm.PackageManager;
26 import android.content.pm.ResolveInfo;
27 import android.content.res.Resources;
28 import android.database.Cursor;
29 import android.graphics.Bitmap;
30 import android.graphics.BitmapFactory;
31 import android.graphics.drawable.Drawable;
32 import android.net.Uri;
33 import static android.util.Log.*;
34 import android.os.Process;
35
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Comparator;
40 import java.util.concurrent.atomic.AtomicInteger;
41 import java.lang.ref.WeakReference;
42 import java.text.Collator;
43 import java.net.URISyntaxException;
44
45
46
47
48
49
50 public class LauncherModel {
51 static final boolean DEBUG_LOADERS = false;
52 static final String LOG_TAG = "HomeLoaders";
53
54 private static final int UI_NOTIFICATION_RATE = 4;
55 private static final int DEFAULT_APPLICATIONS_NUMBER = 42;
56 private static final long APPLICATION_NOT_RESPONDING_TIMEOUT = 5000;
57 private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
58
59 private static final Collator sCollator = Collator.getInstance();
60
61 private boolean mApplicationsLoaded;
62 private boolean mDesktopItemsLoaded;
63
64 private ArrayList<ItemInfo> mDesktopItems;
65 private ArrayList<LauncherAppWidgetInfo> mDesktopAppWidgets;
66 private HashMap<Long, FolderInfo> mFolders;
67
68 private ArrayList<ApplicationInfo> mApplications;
69 private ApplicationsAdapter mApplicationsAdapter;
70 private ApplicationsLoader mApplicationsLoader;
71 private DesktopItemsLoader mDesktopItemsLoader;
72 private Thread mApplicationsLoaderThread;
73 private Thread mDesktopLoaderThread;
74
75 private final HashMap<ComponentName, ApplicationInfo> mAppInfoCache =
76 new HashMap<ComponentName, ApplicationInfo>(INITIAL_ICON_CACHE_CAPACITY);
77
78 synchronized void abortLoaders() {
79 if (DEBUG_LOADERS) d(LOG_TAG, "aborting loaders");
80
81 if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
82 if (DEBUG_LOADERS) d(LOG_TAG, " --> aborting applications loader");
83 mApplicationsLoader.stop();
84 mApplicationsLoaded = false;
85 }
86
87 if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
88 if (DEBUG_LOADERS) d(LOG_TAG, " --> aborting workspace loader");
89 mDesktopItemsLoader.stop();
90 mDesktopItemsLoaded = false;
91 }
92 }
93
94
95
96
97
98
99 synchronized void dropApplicationCache() {
100 mAppInfoCache.clear();
101 }
102
103
104
105
106
107
108
109 synchronized boolean loadApplications(boolean isLaunching, Launcher launcher,
110 boolean localeChanged) {
111
112 if (DEBUG_LOADERS) d(LOG_TAG, "load applications");
113
114 if (isLaunching && mApplicationsLoaded && !localeChanged) {
115 mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
116 if (DEBUG_LOADERS) d(LOG_TAG, " --> applications loaded, return");
117 return false;
118 }
119
120 stopAndWaitForApplicationsLoader();
121
122 if (localeChanged) {
123 dropApplicationCache();
124 }
125
126 if (mApplicationsAdapter == null || isLaunching || localeChanged) {
127 mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER);
128 mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
129 }
130
131 mApplicationsLoaded = false;
132
133 if (!isLaunching) {
134 startApplicationsLoaderLocked(launcher, false);
135 return false;
136 }
137
138 return true;
139 }
140
141 private synchronized void stopAndWaitForApplicationsLoader() {
142 if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
143 if (DEBUG_LOADERS) {
144 d(LOG_TAG, " --> wait for applications loader (" + mApplicationsLoader.mId + ")");
145 }
146
147 mApplicationsLoader.stop();
148
149
150 try {
151 mApplicationsLoaderThread.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
152 } catch (InterruptedException e) {
153
154 }
155 }
156 }
157
158 private synchronized void startApplicationsLoader(Launcher launcher, boolean isLaunching) {
159 if (DEBUG_LOADERS) d(LOG_TAG, " --> starting applications loader unlocked");
160 startApplicationsLoaderLocked(launcher, isLaunching);
161 }
162
163 private void startApplicationsLoaderLocked(Launcher launcher, boolean isLaunching) {
164 if (DEBUG_LOADERS) d(LOG_TAG, " --> starting applications loader");
165
166 stopAndWaitForApplicationsLoader();
167
168 mApplicationsLoader = new ApplicationsLoader(launcher, isLaunching);
169 mApplicationsLoaderThread = new Thread(mApplicationsLoader, "Applications Loader");
170 mApplicationsLoaderThread.start();
171 }
172
173 synchronized void addPackage(Launcher launcher, String packageName) {
174 if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
175 startApplicationsLoaderLocked(launcher, false);
176 return;
177 }
178
179 if (packageName != null && packageName.length() > 0) {
180 final PackageManager packageManager = launcher.getPackageManager();
181 final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
182
183 if (matches.size() > 0) {
184 final ApplicationsAdapter adapter = mApplicationsAdapter;
185 final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
186
187 for (ResolveInfo info : matches) {
188 adapter.setNotifyOnChange(false);
189 adapter.add(makeAndCacheApplicationInfo(packageManager, cache, info, launcher));
190 }
191
192 adapter.sort(new ApplicationInfoComparator());
193 adapter.notifyDataSetChanged();
194 }
195 }
196 }
197
198 synchronized void removePackage(Launcher launcher, String packageName) {
199 if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
200 dropApplicationCache();
201 startApplicationsLoaderLocked(launcher, false);
202 return;
203 }
204
205 if (packageName != null && packageName.length() > 0) {
206 final ApplicationsAdapter adapter = mApplicationsAdapter;
207
208 final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
209 final int count = adapter.getCount();
210
211 for (int i = 0; i < count; i++) {
212 final ApplicationInfo applicationInfo = adapter.getItem(i);
213 final Intent intent = applicationInfo.intent;
214 final ComponentName component = intent.getComponent();
215 if (packageName.equals(component.getPackageName())) {
216 toRemove.add(applicationInfo);
217 }
218 }
219
220 final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
221 for (ApplicationInfo info : toRemove) {
222 adapter.setNotifyOnChange(false);
223 adapter.remove(info);
224 cache.remove(info.intent.getComponent());
225 }
226
227 if (toRemove.size() > 0) {
228 adapter.sort(new ApplicationInfoComparator());
229 adapter.notifyDataSetChanged();
230 }
231 }
232 }
233
234 synchronized void updatePackage(Launcher launcher, String packageName) {
235 if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
236 startApplicationsLoaderLocked(launcher, false);
237 return;
238 }
239
240 if (packageName != null && packageName.length() > 0) {
241 final PackageManager packageManager = launcher.getPackageManager();
242 final ApplicationsAdapter adapter = mApplicationsAdapter;
243
244 final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
245 final int count = matches.size();
246
247 boolean changed = false;
248
249 for (int i = 0; i < count; i++) {
250 final ResolveInfo info = matches.get(i);
251 final ApplicationInfo applicationInfo = findIntent(adapter,
252 info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
253 if (applicationInfo != null) {
254 updateAndCacheApplicationInfo(packageManager, info, applicationInfo, launcher);
255 changed = true;
256 }
257 }
258
259 if (syncLocked(launcher, packageName)) changed = true;
260
261 if (changed) {
262 adapter.sort(new ApplicationInfoComparator());
263 adapter.notifyDataSetChanged();
264 }
265 }
266 }
267
268 private void updateAndCacheApplicationInfo(PackageManager packageManager, ResolveInfo info,
269 ApplicationInfo applicationInfo, Context context) {
270
271 updateApplicationInfoTitleAndIcon(packageManager, info, applicationInfo, context);
272
273 ComponentName componentName = new ComponentName(
274 info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
275 mAppInfoCache.put(componentName, applicationInfo);
276 }
277
278 synchronized void syncPackage(Launcher launcher, String packageName) {
279 if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
280 startApplicationsLoaderLocked(launcher, false);
281 return;
282 }
283
284 if (packageName != null && packageName.length() > 0) {
285 if (syncLocked(launcher, packageName)) {
286 final ApplicationsAdapter adapter = mApplicationsAdapter;
287 adapter.sort(new ApplicationInfoComparator());
288 adapter.notifyDataSetChanged();
289 }
290 }
291 }
292
293 private boolean syncLocked(Launcher launcher, String packageName) {
294 final PackageManager packageManager = launcher.getPackageManager();
295 final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
296
297 if (matches.size() > 0) {
298 final ApplicationsAdapter adapter = mApplicationsAdapter;
299
300
301 boolean removed = removeDisabledActivities(packageName, matches, adapter);
302
303
304 boolean added = addEnabledAndUpdateActivities(matches, adapter, launcher);
305
306 return added || removed;
307 }
308
309 return false;
310 }
311
312 private static List<ResolveInfo> findActivitiesForPackage(PackageManager packageManager,
313 String packageName) {
314
315 final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
316 mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
317
318 final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
319 final List<ResolveInfo> matches = new ArrayList<ResolveInfo>();
320
321 if (apps != null) {
322
323 int count = apps.size();
324 for (int i = 0; i < count; i++) {
325 final ResolveInfo info = apps.get(i);
326 final ActivityInfo activityInfo = info.activityInfo;
327 if (packageName.equals(activityInfo.packageName)) {
328 matches.add(info);
329 }
330 }
331 }
332
333 return matches;
334 }
335
336 private boolean addEnabledAndUpdateActivities(List<ResolveInfo> matches,
337 ApplicationsAdapter adapter, Launcher launcher) {
338
339 final List<ApplicationInfo> toAdd = new ArrayList<ApplicationInfo>();
340 final int count = matches.size();
341
342 boolean changed = false;
343
344 for (int i = 0; i < count; i++) {
345 final ResolveInfo info = matches.get(i);
346 final ApplicationInfo applicationInfo = findIntent(adapter,
347 info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
348 if (applicationInfo == null) {
349 toAdd.add(makeAndCacheApplicationInfo(launcher.getPackageManager(),
350 mAppInfoCache, info, launcher));
351 changed = true;
352 } else {
353 updateAndCacheApplicationInfo(
354 launcher.getPackageManager(), info, applicationInfo, launcher);
355 changed = true;
356 }
357 }
358
359 for (ApplicationInfo info : toAdd) {
360 adapter.setNotifyOnChange(false);
361 adapter.add(info);
362 }
363
364 return changed;
365 }
366
367 private boolean removeDisabledActivities(String packageName, List<ResolveInfo> matches,
368 ApplicationsAdapter adapter) {
369
370 final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
371 final int count = adapter.getCount();
372
373 boolean changed = false;
374
375 for (int i = 0; i < count; i++) {
376 final ApplicationInfo applicationInfo = adapter.getItem(i);
377 final Intent intent = applicationInfo.intent;
378 final ComponentName component = intent.getComponent();
379 if (packageName.equals(component.getPackageName())) {
380 if (!findIntent(matches, component)) {
381 toRemove.add(applicationInfo);
382 changed = true;
383 }
384 }
385 }
386
387 final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
388 for (ApplicationInfo info : toRemove) {
389 adapter.setNotifyOnChange(false);
390 adapter.remove(info);
391 cache.remove(info.intent.getComponent());
392 }
393
394 return changed;
395 }
396
397 private static ApplicationInfo findIntent(ApplicationsAdapter adapter, String packageName,
398 String name) {
399
400 final int count = adapter.getCount();
401 for (int i = 0; i < count; i++) {
402 final ApplicationInfo applicationInfo = adapter.getItem(i);
403 final Intent intent = applicationInfo.intent;
404 final ComponentName component = intent.getComponent();
405 if (packageName.equals(component.getPackageName()) &&
406 name.equals(component.getClassName())) {
407 return applicationInfo;
408 }
409 }
410
411 return null;
412 }
413
414 private static boolean findIntent(List<ResolveInfo> apps, ComponentName component) {
415 final String className = component.getClassName();
416 for (ResolveInfo info : apps) {
417 final ActivityInfo activityInfo = info.activityInfo;
418 if (activityInfo.name.equals(className)) {
419 return true;
420 }
421 }
422 return false;
423 }
424
425 Drawable getApplicationInfoIcon(PackageManager manager, ApplicationInfo info) {
426 final ResolveInfo resolveInfo = manager.resolveActivity(info.intent, 0);
427 if (resolveInfo == null) {
428 return null;
429 }
430
431 ComponentName componentName = new ComponentName(
432 resolveInfo.activityInfo.applicationInfo.packageName,
433 resolveInfo.activityInfo.name);
434 ApplicationInfo application = mAppInfoCache.get(componentName);
435
436 if (application == null) {
437 return resolveInfo.activityInfo.loadIcon(manager);
438 }
439
440 return application.icon;
441 }
442
443 private static ApplicationInfo makeAndCacheApplicationInfo(PackageManager manager,
444 HashMap<ComponentName, ApplicationInfo> appInfoCache, ResolveInfo info,
445 Context context) {
446
447 ComponentName componentName = new ComponentName(
448 info.activityInfo.applicationInfo.packageName,
449 info.activityInfo.name);
450 ApplicationInfo application = appInfoCache.get(componentName);
451
452 if (application == null) {
453 application = new ApplicationInfo();
454 application.container = ItemInfo.NO_ID;
455
456 updateApplicationInfoTitleAndIcon(manager, info, application, context);
457
458 application.setActivity(componentName,
459 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
460
461 appInfoCache.put(componentName, application);
462 }
463
464 return application;
465 }
466
467 private static void updateApplicationInfoTitleAndIcon(PackageManager manager, ResolveInfo info,
468 ApplicationInfo application, Context context) {
469
470 application.title = info.loadLabel(manager);
471 if (application.title == null) {
472 application.title = info.activityInfo.name;
473 }
474
475 application.icon =
476 Utilities.createIconThumbnail(info.activityInfo.loadIcon(manager), context);
477 application.filtered = false;
478 }
479
480 private static final AtomicInteger sAppsLoaderCount = new AtomicInteger(1);
481 private static final AtomicInteger sWorkspaceLoaderCount = new AtomicInteger(1);
482
483 private class ApplicationsLoader implements Runnable {
484 private final WeakReference<Launcher> mLauncher;
485
486 private volatile boolean mStopped;
487 private volatile boolean mRunning;
488 private final boolean mIsLaunching;
489 private final int mId;
490
491 ApplicationsLoader(Launcher launcher, boolean isLaunching) {
492 mIsLaunching = isLaunching;
493 mLauncher = new WeakReference<Launcher>(launcher);
494 mRunning = true;
495 mId = sAppsLoaderCount.getAndIncrement();
496 }
497
498 void stop() {
499 mStopped = true;
500 }
501
502 boolean isRunning() {
503 return mRunning;
504 }
505
506 public void run() {
507 if (DEBUG_LOADERS) d(LOG_TAG, " ----> running applications loader (" + mId + ")");
508
509
510
511 android.os.Process.setThreadPriority(mIsLaunching ? Process.THREAD_PRIORITY_DEFAULT :
512 Process.THREAD_PRIORITY_BACKGROUND);
513
514 final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
515 mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
516
517 final Launcher launcher = mLauncher.get();
518 final PackageManager manager = launcher.getPackageManager();
519 final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
520
521 if (apps != null && !mStopped) {
522 final int count = apps.size();
523
524
525 final ApplicationsAdapter applicationList = mApplicationsAdapter;
526
527 ChangeNotifier action = new ChangeNotifier(applicationList, true);
528 final HashMap<ComponentName, ApplicationInfo> appInfoCache = mAppInfoCache;
529
530 for (int i = 0; i < count && !mStopped; i++) {
531 ResolveInfo info = apps.get(i);
532 ApplicationInfo application =
533 makeAndCacheApplicationInfo(manager, appInfoCache, info, launcher);
534
535 if (action.add(application) && !mStopped) {
536 launcher.runOnUiThread(action);
537 action = new ChangeNotifier(applicationList, false);
538 }
539 }
540
541 launcher.runOnUiThread(action);
542 }
543
544 if (!mStopped) {
545 mApplicationsLoaded = true;
546 } else {
547 if (DEBUG_LOADERS) d(LOG_TAG, " ----> applications loader stopped (" + mId + ")");
548 }
549 mRunning = false;
550 }
551 }
552
553 private static class ChangeNotifier implements Runnable {
554 private final ApplicationsAdapter mApplicationList;
555 private final ArrayList<ApplicationInfo> mBuffer;
556
557 private boolean mFirst = true;
558
559 ChangeNotifier(ApplicationsAdapter applicationList, boolean first) {
560 mApplicationList = applicationList;
561 mFirst = first;
562 mBuffer = new ArrayList<ApplicationInfo>(UI_NOTIFICATION_RATE);
563 }
564
565 public void run() {
566 final ApplicationsAdapter applicationList = mApplicationList;
567
568 if (applicationList == null) return;
569
570 if (mFirst) {
571 applicationList.setNotifyOnChange(false);
572 applicationList.clear();
573 if (DEBUG_LOADERS) d(LOG_TAG, " ----> cleared application list");
574 mFirst = false;
575 }
576
577 final ArrayList<ApplicationInfo> buffer = mBuffer;
578 final int count = buffer.size();
579
580 for (int i = 0; i < count; i++) {
581 applicationList.setNotifyOnChange(false);
582 applicationList.add(buffer.get(i));
583 }
584
585 buffer.clear();
586
587 applicationList.sort(new ApplicationInfoComparator());
588 applicationList.notifyDataSetChanged();
589 }
590
591 boolean add(ApplicationInfo application) {
592 final ArrayList<ApplicationInfo> buffer = mBuffer;
593 buffer.add(application);
594 return buffer.size() >= UI_NOTIFICATION_RATE;
595 }
596 }
597
598 static class ApplicationInfoComparator implements Comparator<ApplicationInfo> {
599 public final int compare(ApplicationInfo a, ApplicationInfo b) {
600 return sCollator.compare(a.title.toString(), b.title.toString());
601 }
602 }
603
604 boolean isDesktopLoaded() {
605 return mDesktopItems != null && mDesktopAppWidgets != null && mDesktopItemsLoaded;
606 }
607
608
609
610
611
612 void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged,
613 boolean loadApplications) {
614 if (DEBUG_LOADERS) d(LOG_TAG, "loading user items");
615
616 if (isLaunching && isDesktopLoaded()) {
617 if (DEBUG_LOADERS) d(LOG_TAG, " --> items loaded, return");
618 if (loadApplications) startApplicationsLoader(launcher, true);
619
620 launcher.onDesktopItemsLoaded(mDesktopItems, mDesktopAppWidgets);
621 return;
622 }
623
624 if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
625 if (DEBUG_LOADERS) d(LOG_TAG, " --> stopping workspace loader");
626 mDesktopItemsLoader.stop();
627
628
629 try {
630 mDesktopLoaderThread.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
631 } catch (InterruptedException e) {
632
633 }
634
635
636
637
638
639
640 loadApplications = mDesktopItemsLoader.mLoadApplications;
641 }
642
643 if (DEBUG_LOADERS) d(LOG_TAG, " --> starting workspace loader");
644 mDesktopItemsLoaded = false;
645 mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications,
646 isLaunching);
647 mDesktopLoaderThread = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
648 mDesktopLoaderThread.start();
649 }
650
651 private static void updateShortcutLabels(ContentResolver resolver, PackageManager manager) {
652 final Cursor c = resolver.query(LauncherSettings.Favorites.CONTENT_URI,
653 new String[] { LauncherSettings.Favorites._ID, LauncherSettings.Favorites.TITLE,
654 LauncherSettings.Favorites.INTENT, LauncherSettings.Favorites.ITEM_TYPE },
655 null, null, null);
656
657 final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
658 final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
659 final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
660 final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
661
662
663
664 try {
665 while (c.moveToNext()) {
666 try {
667 if (c.getInt(itemTypeIndex) !=
668 LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
669 continue;
670 }
671
672 final String intentUri = c.getString(intentIndex);
673 if (intentUri != null) {
674 final Intent shortcut = Intent.parseUri(intentUri, 0);
675 if (Intent.ACTION_MAIN.equals(shortcut.getAction())) {
676 final ComponentName name = shortcut.getComponent();
677 if (name != null) {
678 final ActivityInfo activityInfo = manager.getActivityInfo(name, 0);
679 final String title = c.getString(titleIndex);
680 String label = getLabel(manager, activityInfo);
681
682 if (title == null || !title.equals(label)) {
683 final ContentValues values = new ContentValues();
684 values.put(LauncherSettings.Favorites.TITLE, label);
685
686 resolver.update(
687 LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
688 values, "_id=?",
689 new String[] { String.valueOf(c.getLong(idIndex)) });
690
691
692 }
693 }
694 }
695 }
696 } catch (URISyntaxException e) {
697
698 } catch (PackageManager.NameNotFoundException e) {
699
700 }
701 }
702 } finally {
703 c.close();
704 }
705
706
707 }
708
709 private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
710 String label = activityInfo.loadLabel(manager).toString();
711 if (label == null) {
712 label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
713 if (label == null) {
714 label = activityInfo.name;
715 }
716 }
717 return label;
718 }
719
720 private class DesktopItemsLoader implements Runnable {
721 private volatile boolean mStopped;
722 private volatile boolean mRunning;
723
724 private final WeakReference<Launcher> mLauncher;
725 private final boolean mLocaleChanged;
726 private final boolean mLoadApplications;
727 private final boolean mIsLaunching;
728 private final int mId;
729
730 DesktopItemsLoader(Launcher launcher, boolean localeChanged, boolean loadApplications,
731 boolean isLaunching) {
732 mLoadApplications = loadApplications;
733 mIsLaunching = isLaunching;
734 mLauncher = new WeakReference<Launcher>(launcher);
735 mLocaleChanged = localeChanged;
736 mId = sWorkspaceLoaderCount.getAndIncrement();
737 }
738
739 void stop() {
740 mStopped = true;
741 }
742
743 boolean isRunning() {
744 return mRunning;
745 }
746
747 public void run() {
748 if (DEBUG_LOADERS) d(LOG_TAG, " ----> running workspace loader (" + mId + ")");
749
750 mRunning = true;
751
752 android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
753
754 final Launcher launcher = mLauncher.get();
755 final ContentResolver contentResolver = launcher.getContentResolver();
756 final PackageManager manager = launcher.getPackageManager();
757
758 if (mLocaleChanged) {
759 updateShortcutLabels(contentResolver, manager);
760 }
761
762 mDesktopItems = new ArrayList<ItemInfo>();
763 mDesktopAppWidgets = new ArrayList<LauncherAppWidgetInfo>();
764 mFolders = new HashMap<Long, FolderInfo>();
765
766 final ArrayList<ItemInfo> desktopItems = mDesktopItems;
767 final ArrayList<LauncherAppWidgetInfo> desktopAppWidgets = mDesktopAppWidgets;
768
769 final Cursor c = contentResolver.query(
770 LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
771
772 try {
773 final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
774 final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
775 final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
776 final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
777 final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
778 final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
779 final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
780 final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
781 final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
782 final int appWidgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.APPWIDGET_ID);
783 final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
784 final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
785 final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
786 final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
787 final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
788 final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
789 final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
790
791 ApplicationInfo info;
792 String intentDescription;
793 Widget widgetInfo;
794 LauncherAppWidgetInfo appWidgetInfo;
795 int container;
796 long id;
797 Intent intent;
798
799 final HashMap<Long, FolderInfo> folders = mFolders;
800
801 while (!mStopped && c.moveToNext()) {
802 try {
803 int itemType = c.getInt(itemTypeIndex);
804
805 switch (itemType) {
806 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
807 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
808 intentDescription = c.getString(intentIndex);
809 try {
810 intent = Intent.parseUri(intentDescription, 0);
811 } catch (java.net.URISyntaxException e) {
812 continue;
813 }
814
815 if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
816 info = getApplicationInfo(manager, intent, launcher);
817 } else {
818 info = getApplicationInfoShortcut(c, launcher, iconTypeIndex,
819 iconPackageIndex, iconResourceIndex, iconIndex);
820 }
821
822 if (info == null) {
823 info = new ApplicationInfo();
824 info.icon = manager.getDefaultActivityIcon();
825 }
826
827 if (info != null) {
828 info.title = c.getString(titleIndex);
829 info.intent = intent;
830
831 info.id = c.getLong(idIndex);
832 container = c.getInt(containerIndex);
833 info.container = container;
834 info.screen = c.getInt(screenIndex);
835 info.cellX = c.getInt(cellXIndex);
836 info.cellY = c.getInt(cellYIndex);
837
838 switch (container) {
839 case LauncherSettings.Favorites.CONTAINER_DESKTOP:
840 desktopItems.add(info);
841 break;
842 default:
843
844 UserFolderInfo folderInfo =
845 findOrMakeUserFolder(folders, container);
846 folderInfo.add(info);
847 break;
848 }
849 }
850 break;
851 case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
852
853 id = c.getLong(idIndex);
854 UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id);
855
856 folderInfo.title = c.getString(titleIndex);
857
858 folderInfo.id = id;
859 container = c.getInt(containerIndex);
860 folderInfo.container = container;
861 folderInfo.screen = c.getInt(screenIndex);
862 folderInfo.cellX = c.getInt(cellXIndex);
863 folderInfo.cellY = c.getInt(cellYIndex);
864
865 switch (container) {
866 case LauncherSettings.Favorites.CONTAINER_DESKTOP:
867 desktopItems.add(folderInfo);
868 break;
869 }
870 break;
871 case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
872
873 id = c.getLong(idIndex);
874 LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(folders, id);
875
876 intentDescription = c.getString(intentIndex);
877 intent = null;
878 if (intentDescription != null) {
879 try {
880 intent = Intent.parseUri(intentDescription, 0);
881 } catch (java.net.URISyntaxException e) {
882
883 }
884 }
885
886 liveFolderInfo.title = c.getString(titleIndex);
887 liveFolderInfo.id = id;
888 container = c.getInt(containerIndex);
889 liveFolderInfo.container = container;
890 liveFolderInfo.screen = c.getInt(screenIndex);
891 liveFolderInfo.cellX = c.getInt(cellXIndex);
892 liveFolderInfo.cellY = c.getInt(cellYIndex);
893 liveFolderInfo.uri = Uri.parse(c.getString(uriIndex));
894 liveFolderInfo.baseIntent = intent;
895 liveFolderInfo.displayMode = c.getInt(displayModeIndex);
896
897 loadLiveFolderIcon(launcher, c, iconTypeIndex, iconPackageIndex,
898 iconResourceIndex, liveFolderInfo);
899
900 switch (container) {
901 case LauncherSettings.Favorites.CONTAINER_DESKTOP:
902 desktopItems.add(liveFolderInfo);
903 break;
904 }
905 break;
906 case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
907 widgetInfo = Widget.makeSearch();
908
909 container = c.getInt(containerIndex);
910 if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
911 e(Launcher.LOG_TAG, "Widget found where container "
912 + "!= CONTAINER_DESKTOP ignoring!");
913 continue;
914 }
915
916 widgetInfo.id = c.getLong(idIndex);
917 widgetInfo.screen = c.getInt(screenIndex);
918 widgetInfo.container = container;
919 widgetInfo.cellX = c.getInt(cellXIndex);
920 widgetInfo.cellY = c.getInt(cellYIndex);
921
922 desktopItems.add(widgetInfo);
923 break;
924 case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
925
926 int appWidgetId = c.getInt(appWidgetIdIndex);
927 appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId);
928 appWidgetInfo.id = c.getLong(idIndex);
929 appWidgetInfo.screen = c.getInt(screenIndex);
930 appWidgetInfo.cellX = c.getInt(cellXIndex);
931 appWidgetInfo.cellY = c.getInt(cellYIndex);
932 appWidgetInfo.spanX = c.getInt(spanXIndex);
933 appWidgetInfo.spanY = c.getInt(spanYIndex);
934
935 container = c.getInt(containerIndex);
936 if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
937 e(Launcher.LOG_TAG, "Widget found where container "
938 + "!= CONTAINER_DESKTOP -- ignoring!");
939 continue;
940 }
941 appWidgetInfo.container = c.getInt(containerIndex);
942
943 desktopAppWidgets.add(appWidgetInfo);
944 break;
945 }
946 } catch (Exception e) {
947 w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
948 }
949 }
950 } finally {
951 c.close();
952 }
953
954 if (!mStopped) {
955 if (DEBUG_LOADERS) {
956 d(LOG_TAG, " --> done loading workspace");
957 d(LOG_TAG, " ----> worskpace items=" + desktopItems.size());
958 d(LOG_TAG, " ----> worskpace widgets=" + desktopAppWidgets.size());
959 }
960
961
962
963 final ArrayList<ItemInfo> uiDesktopItems =
964 new ArrayList<ItemInfo>(desktopItems);
965 final ArrayList<LauncherAppWidgetInfo> uiDesktopWidgets =
966 new ArrayList<LauncherAppWidgetInfo>(desktopAppWidgets);
967
968 if (!mStopped) {
969 d(LOG_TAG, " ----> items cloned, ready to refresh UI");
970 launcher.runOnUiThread(new Runnable() {
971 public void run() {
972 if (DEBUG_LOADERS) d(LOG_TAG, " ----> onDesktopItemsLoaded()");
973 launcher.onDesktopItemsLoaded(uiDesktopItems, uiDesktopWidgets);
974 }
975 });
976 }
977
978 if (mLoadApplications) {
979 if (DEBUG_LOADERS) {
980 d(LOG_TAG, " ----> loading applications from workspace loader");
981 }
982 startApplicationsLoader(launcher, mIsLaunching);
983 }
984
985 mDesktopItemsLoaded = true;
986 } else {
987 if (DEBUG_LOADERS) d(LOG_TAG, " ----> worskpace loader was stopped");
988 }
989 mRunning = false;
990 }
991 }
992
993 private static void loadLiveFolderIcon(Launcher launcher, Cursor c, int iconTypeIndex,
994 int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
995
996 int iconType = c.getInt(iconTypeIndex);
997 switch (iconType) {
998 case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
999 String packageName = c.getString(iconPackageIndex);
1000 String resourceName = c.getString(iconResourceIndex);
1001 PackageManager packageManager = launcher.getPackageManager();
1002 try {
1003 Resources resources = packageManager.getResourcesForApplication(packageName);
1004 final int id = resources.getIdentifier(resourceName, null, null);
1005 liveFolderInfo.icon = resources.getDrawable(id);
1006 } catch (Exception e) {
1007 liveFolderInfo.icon =
1008 launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
1009 }
1010 liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
1011 liveFolderInfo.iconResource.packageName = packageName;
1012 liveFolderInfo.iconResource.resourceName = resourceName;
1013 break;
1014 default:
1015 liveFolderInfo.icon =
1016 launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
1017 }
1018 }
1019
1020
1021
1022
1023
1024
1025
1026
1027 FolderInfo findFolderById(long id) {
1028 return mFolders.get(id);
1029 }
1030
1031 void addFolder(FolderInfo info) {
1032 mFolders.put(info.id, info);
1033 }
1034
1035
1036
1037
1038
1039 private UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
1040
1041 FolderInfo folderInfo = folders.get(id);
1042 if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
1043
1044 folderInfo = new UserFolderInfo();
1045 folders.put(id, folderInfo);
1046 }
1047 return (UserFolderInfo) folderInfo;
1048 }
1049
1050
1051
1052
1053
1054 private LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
1055
1056 FolderInfo folderInfo = folders.get(id);
1057 if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
1058
1059 folderInfo = new LiveFolderInfo();
1060 folders.put(id, folderInfo);
1061 }
1062 return (LiveFolderInfo) folderInfo;
1063 }
1064
1065
1066
1067
1068
1069 void unbind() {
1070
1071 stopAndWaitForApplicationsLoader();
1072 mApplicationsAdapter = null;
1073 unbindAppDrawables(mApplications);
1074 unbindDrawables(mDesktopItems);
1075 unbindAppWidgetHostViews(mDesktopAppWidgets);
1076 unbindCachedIconDrawables();
1077 }
1078
1079
1080
1081
1082
1083 private void unbindDrawables(ArrayList<ItemInfo> desktopItems) {
1084 if (desktopItems != null) {
1085 final int count = desktopItems.size();
1086 for (int i = 0; i < count; i++) {
1087 ItemInfo item = desktopItems.get(i);
1088 switch (item.itemType) {
1089 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
1090 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
1091 ((ApplicationInfo)item).icon.setCallback(null);
1092 break;
1093 }
1094 }
1095 }
1096 }
1097
1098
1099
1100
1101
1102 private void unbindAppDrawables(ArrayList<ApplicationInfo> applications) {
1103 if (applications != null) {
1104 final int count = applications.size();
1105 for (int i = 0; i < count; i++) {
1106 applications.get(i).icon.setCallback(null);
1107 }
1108 }
1109 }
1110
1111
1112
1113
1114 private void unbindAppWidgetHostViews(ArrayList<LauncherAppWidgetInfo> appWidgets) {
1115 if (appWidgets != null) {
1116 final int count = appWidgets.size();
1117 for (int i = 0; i < count; i++) {
1118 LauncherAppWidgetInfo launcherInfo = appWidgets.get(i);
1119 launcherInfo.hostView = null;
1120 }
1121 }
1122 }
1123
1124
1125
1126
1127
1128 private void unbindCachedIconDrawables() {
1129 for (ApplicationInfo appInfo : mAppInfoCache.values()) {
1130 appInfo.icon.setCallback(null);
1131 }
1132 }
1133
1134
1135
1136
1137
1138 void findAllOccupiedCells(boolean[][] occupied, int countX, int countY, int screen) {
1139 final ArrayList<ItemInfo> desktopItems = mDesktopItems;
1140 if (desktopItems != null) {
1141 final int count = desktopItems.size();
1142 for (int i = 0; i < count; i++) {
1143 ItemInfo item = desktopItems.get(i);
1144 addOccupiedCells(occupied, screen, desktopItems.get(i));
1145 }
1146 }
1147
1148 final ArrayList<LauncherAppWidgetInfo> desktopAppWidgets = mDesktopAppWidgets;
1149 if (desktopAppWidgets != null) {
1150 final int count = desktopAppWidgets.size();
1151 for (int i = 0; i < count; i++) {
1152 addOccupiedCells(occupied, screen, desktopAppWidgets.get(i));
1153 }
1154 }
1155 }
1156
1157
1158
1159
1160 private void addOccupiedCells(boolean[][] occupied, int screen,
1161 ItemInfo item) {
1162 if (item.screen == screen) {
1163 for (int xx = item.cellX; xx < item.cellX + item.spanX; xx++) {
1164 for (int yy = item.cellY; yy < item.cellY + item.spanY; yy++) {
1165 occupied[xx][yy] = true;
1166 }
1167 }
1168 }
1169 }
1170
1171
1172
1173
1174 ApplicationsAdapter getApplicationsAdapter() {
1175 return mApplicationsAdapter;
1176 }
1177
1178
1179
1180
1181
1182 void addDesktopItem(ItemInfo info) {
1183
1184 mDesktopItems.add(info);
1185 }
1186
1187
1188
1189
1190
1191 void removeDesktopItem(ItemInfo info) {
1192
1193 mDesktopItems.remove(info);
1194 }
1195
1196
1197
1198
1199 void addDesktopAppWidget(LauncherAppWidgetInfo info) {
1200 mDesktopAppWidgets.add(info);
1201 }
1202
1203
1204
1205
1206 void removeDesktopAppWidget(LauncherAppWidgetInfo info) {
1207 mDesktopAppWidgets.remove(info);
1208 }
1209
1210
1211
1212
1213 private static ApplicationInfo getApplicationInfo(PackageManager manager, Intent intent,
1214 Context context) {
1215 final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
1216
1217 if (resolveInfo == null) {
1218 return null;
1219 }
1220
1221 final ApplicationInfo info = new ApplicationInfo();
1222 final ActivityInfo activityInfo = resolveInfo.activityInfo;
1223 info.icon = Utilities.createIconThumbnail(activityInfo.loadIcon(manager), context);
1224 if (info.title == null || info.title.length() == 0) {
1225 info.title = activityInfo.loadLabel(manager);
1226 }
1227 if (info.title == null) {
1228 info.title = "";
1229 }
1230 info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
1231 return info;
1232 }
1233
1234
1235
1236
1237 private ApplicationInfo getApplicationInfoShortcut(Cursor c, Context context,
1238 int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) {
1239
1240 final ApplicationInfo info = new ApplicationInfo();
1241 info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
1242
1243 int iconType = c.getInt(iconTypeIndex);
1244 switch (iconType) {
1245 case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
1246 String packageName = c.getString(iconPackageIndex);
1247 String resourceName = c.getString(iconResourceIndex);
1248 PackageManager packageManager = context.getPackageManager();
1249 try {
1250 Resources resources = packageManager.getResourcesForApplication(packageName);
1251 final int id = resources.getIdentifier(resourceName, null, null);
1252 info.icon = Utilities.createIconThumbnail(resources.getDrawable(id), context);
1253 } catch (Exception e) {
1254 info.icon = packageManager.getDefaultActivityIcon();
1255 }
1256 info.iconResource = new Intent.ShortcutIconResource();
1257 info.iconResource.packageName = packageName;
1258 info.iconResource.resourceName = resourceName;
1259 info.customIcon = false;
1260 break;
1261 case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
1262 byte[] data = c.getBlob(iconIndex);
1263 try {
1264 Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
1265 info.icon = new FastBitmapDrawable(
1266 Utilities.createBitmapThumbnail(bitmap, context));
1267 } catch (Exception e) {
1268 packageManager = context.getPackageManager();
1269 info.icon = packageManager.getDefaultActivityIcon();
1270 }
1271 info.filtered = true;
1272 info.customIcon = true;
1273 break;
1274 default:
1275 info.icon = context.getPackageManager().getDefaultActivityIcon();
1276 info.customIcon = false;
1277 break;
1278 }
1279 return info;
1280 }
1281
1282
1283
1284
1285 void removeUserFolderItem(UserFolderInfo folder, ItemInfo info) {
1286
1287 folder.contents.remove(info);
1288 }
1289
1290
1291
1292
1293
1294 void removeUserFolder(UserFolderInfo userFolderInfo) {
1295 mFolders.remove(userFolderInfo.id);
1296 }
1297
1298
1299
1300
1301
1302 static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
1303 int screen, int cellX, int cellY) {
1304 if (item.container == ItemInfo.NO_ID) {
1305
1306 addItemToDatabase(context, item, container, screen, cellX, cellY, false);
1307 } else {
1308
1309 moveItemInDatabase(context, item, container, screen, cellX, cellY);
1310 }
1311 }
1312
1313
1314
1315
1316 static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen,
1317 int cellX, int cellY) {
1318 item.container = container;
1319 item.screen = screen;
1320 item.cellX = cellX;
1321 item.cellY = cellY;
1322
1323 final ContentValues values = new ContentValues();
1324 final ContentResolver cr = context.getContentResolver();
1325
1326 values.put(LauncherSettings.Favorites.CONTAINER, item.container);
1327 values.put(LauncherSettings.Favorites.CELLX, item.cellX);
1328 values.put(LauncherSettings.Favorites.CELLY, item.cellY);
1329 values.put(LauncherSettings.Favorites.SCREEN, item.screen);
1330
1331 cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
1332 }
1333
1334
1335
1336
1337
1338 static boolean shortcutExists(Context context, String title, Intent intent) {
1339 final ContentResolver cr = context.getContentResolver();
1340 Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
1341 new String[] { "title", "intent" }, "title=? and intent=?",
1342 new String[] { title, intent.toUri(0) }, null);
1343 boolean result = false;
1344 try {
1345 result = c.moveToFirst();
1346 } finally {
1347 c.close();
1348 }
1349 return result;
1350 }
1351
1352 FolderInfo getFolderById(Context context, long id) {
1353 final ContentResolver cr = context.getContentResolver();
1354 Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
1355 "_id=? and (itemType=? or itemType=?)",
1356 new String[] { String.valueOf(id),
1357 String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
1358 String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
1359
1360 try {
1361 if (c.moveToFirst()) {
1362 final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
1363 final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
1364 final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
1365 final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
1366 final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
1367 final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
1368
1369 FolderInfo folderInfo = null;
1370 switch (c.getInt(itemTypeIndex)) {
1371 case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
1372 folderInfo = findOrMakeUserFolder(mFolders, id);
1373 break;
1374 case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
1375 folderInfo = findOrMakeLiveFolder(mFolders, id);
1376 break;
1377 }
1378
1379 folderInfo.title = c.getString(titleIndex);
1380 folderInfo.id = id;
1381 folderInfo.container = c.getInt(containerIndex);
1382 folderInfo.screen = c.getInt(screenIndex);
1383 folderInfo.cellX = c.getInt(cellXIndex);
1384 folderInfo.cellY = c.getInt(cellYIndex);
1385
1386 return folderInfo;
1387 }
1388 } finally {
1389 c.close();
1390 }
1391
1392 return null;
1393 }
1394
1395
1396
1397
1398
1399 static void addItemToDatabase(Context context, ItemInfo item, long container,
1400 int screen, int cellX, int cellY, boolean notify) {
1401 item.container = container;
1402 item.screen = screen;
1403 item.cellX = cellX;
1404 item.cellY = cellY;
1405
1406 final ContentValues values = new ContentValues();
1407 final ContentResolver cr = context.getContentResolver();
1408
1409 item.onAddToDatabase(values);
1410
1411 Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
1412 LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
1413
1414 if (result != null) {
1415 item.id = Integer.parseInt(result.getPathSegments().get(1));
1416 }
1417 }
1418
1419
1420
1421
1422 static void updateItemInDatabase(Context context, ItemInfo item) {
1423 final ContentValues values = new ContentValues();
1424 final ContentResolver cr = context.getContentResolver();
1425
1426 item.onAddToDatabase(values);
1427
1428 cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
1429 }
1430
1431
1432
1433
1434
1435
1436 static void deleteItemFromDatabase(Context context, ItemInfo item) {
1437 final ContentResolver cr = context.getContentResolver();
1438
1439 cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
1440 }
1441
1442
1443
1444
1445
1446 static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
1447 final ContentResolver cr = context.getContentResolver();
1448
1449 cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
1450 cr.delete(LauncherSettings.Favorites.CONTENT_URI,
1451 LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
1452 }
1453 }